﻿using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TestCluster.usermodels;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Z.EntityFramework.Plus;

namespace TestCluster.usermodels
{
    /// <summary>
    /// 部门信息
    ///</summary>
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "add" })]
    public class PartInfoAppService : TestClusterAppService
    {
        /// <summary>
        /// 
        /// </summary>
        //private readonly IRepository<PartInfo, int> _repository;

        private readonly ITestClusterDbContext _dbContext;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbContext"></param>
        public PartInfoAppService(ITestClusterDbContext dbContext)
        {
            //_repository = repository;
            _dbContext = dbContext;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PagedResultDto<PartInfoListDto>> GetListAsync(int page = 1, int size = 20)
        {

            var query = _dbContext.PartInfo.Where(t => 1 == 1).AsNoTracking().OrderBy(xy => xy.FatherStr).ThenBy(x => x.Level);

            var pagedResultDto = new PagedResultDto<PartInfoListDto>();
            pagedResultDto.TotalCount = await query.CountAsync();
            var userList = await query.Page(page, size).ToListAsync();
            var temList = ObjectMapper.Map<List<PartInfo>, List<PartInfoListDto>>(userList);
            pagedResultDto.Items = temList;
            return pagedResultDto;
        }

        /// <summary>
        /// 根据ID获取单项部门信息
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public PartInfoDto GetByIdAsync(int id)
        {
            var query = _dbContext.PartInfo.Where(t => t.Id == id).AsNoTracking().FirstOrDefault();
            var temList = ObjectMapper.Map<PartInfo, PartInfoDto>(query);
            return temList;
        }

        /// <summary>
        /// 根据ID获取待更新单项信息部门信息
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public PartInfoUpdateDto GetInfoForUpdateAsync(int id)
        {
            var query = _dbContext.PartInfo.Where(t => t.Id == id).AsNoTracking().FirstOrDefault();
            var temList = ObjectMapper.Map<PartInfo, PartInfoUpdateDto>(query);
            return temList;
        }


        /// <summary>
        /// 添加一个部门信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PartInfoDto> CreateItemAsync(PartInfoAddDto input)
        {

            var newu = ObjectMapper.Map<PartInfoAddDto, PartInfo>(input);

            newu.FatherId = 0;
            newu.FatherStr = "";
            newu.Level = 0;
            //添加自定义
            _dbContext.PartInfo.Add(newu);

            await _dbContext.SaveChangesAsync();

            if (input.FatherId != 0)
            {
                var father = _dbContext.PartInfo.Where(x => x.Id == input.FatherId).AsNoTracking().FirstOrDefault();
                if (father != null && father != default)
                {
                    await _dbContext.PartInfo.Where(x => x.Id == newu.Id).UpdateAsync(x => new PartInfo() { FatherStr = $"{father.FatherStr}{newu.Id},", Level = (father.Level + 1), FatherId = father.Id });
                }
                else
                {
                    input.FatherId = 0;
                }
            }

            if (input.FatherId == 0)
            {
                await _dbContext.PartInfo.Where(x => x.Id == newu.Id).UpdateAsync(x => new PartInfo() { FatherStr = $"{newu.Id}," });
            }

            var backinfo = ObjectMapper.Map<PartInfo, PartInfoDto>(newu);
            return backinfo;
        }
        /// <summary>
        /// 更新一个部门信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PartInfoDto> UpdateItemAsync(PartInfoUpdateDto input)
        {
            var info = await _dbContext.PartInfo.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
            if (info == null || info == default)
            {
                throw new TestClusterException("需要查询的信息不存在", "404");
            }

            var ofid = info.FatherId;
            var nfid = input.FatherId;

            ObjectMapper.Map<PartInfoUpdateDto, PartInfo>(input, info);

            if (ofid != nfid)
            {
                //层级差
                var chalevel = 0;
                var nfatherstr = $"{info.Id},";
                var ofatherstr = info.FatherStr;//1,2,3,4,6, id.id=6
                var father = _dbContext.PartInfo.Where(x => x.Id == nfid).AsNoTracking().FirstOrDefault();
                if (father != null && father != default)
                {
                    chalevel = (father.Level + 1) - info.Level;
                    nfatherstr = $"{father.FatherStr}{info.Id},";
                    info.FatherId = nfid;
                    info.Level = father.Level + 1;
                    info.FatherStr = nfatherstr;
                }
                else
                {
                    chalevel = 0 - info.Level;
                    info.FatherId = 0;
                    info.Level = 0;
                    info.FatherStr = $"{info.Id},";
                }
                //fatherid fatherstr level
                //更换了父级ID
                if (ofatherstr != nfatherstr)
                {
                    var suns = _dbContext.PartInfo.Where(x => x.Id != info.Id && x.FatherStr.StartsWith(ofatherstr)).ToList();
                    if (suns != null && suns.Count > 0)
                    {
                        foreach (var item in suns)
                        {
                            item.FatherStr = item.FatherStr.Replace(ofatherstr, nfatherstr);
                            item.Level = item.Level + chalevel;
                        }
                    }
                }
            }
            await _dbContext.SaveChangesAsync();
            var backinfo = ObjectMapper.Map<PartInfo, PartInfoDto>(info);
            return backinfo;
        }

        /// <summary>
        /// 删除部门信息 会删除绑定的关系
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<int> DeleteItemById(int id)
        {
            var aione = await _dbContext.PartInfo.Where(xy => xy.Id == id).FirstOrDefaultAsync();//.FirstOrDefault();
            if (aione != default)
            {
                //删除所有相关的绑定
                var binds = await _dbContext.BindUserPart.Where(x => x.PartId == aione.Id).ToListAsync();

                if (binds != null && binds.Count > 0)
                {
                    _dbContext.RemoveRange(binds);
                }

                _dbContext.Remove(aione);
                await _dbContext.SaveChangesAsync();
                //await _repository.DeleteAsync(aione);
            }
            return 1;
        }

    }
}
